package br.com.sgmf.web.validator;

import org.springframework.stereotype.Component;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

@Component("cnpjValidator")
public class CNPJValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        value = removeMask(String.valueOf(value));

        if (!validaCNPJ(String.valueOf(value))) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "CNPJ: Erro de validação: número de CNPJ inválido", null);
            throw new ValidatorException(message);
        }
    }

    public static String removeMask(String value) {
        String cnpj = value;

        if (value != null && !value.equals("")) {
            cnpj = value.replaceAll("\\.", "").replaceAll("\\-", "").replaceAll("/", "");
        }

        return cnpj;
    }

    public static boolean validaCNPJ(String cnpj) {
        if (cnpj == null || cnpj.length() != 14) {
            return false;
        }

        try {
            Long.parseLong(cnpj);
        } catch (NumberFormatException e) {
            return false;
        }

        int soma = 0;
        String cnpj_calc = cnpj.substring(0, 12);

        char chr_cnpj[] = cnpj.toCharArray();
        for (int i = 0; i < 4; i++) {
            if (chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9) {
                soma += (chr_cnpj[i] - 48) * (6 - (i + 1));
            }
        }

        for (int i = 0; i < 8; i++) {
            if (chr_cnpj[i + 4] - 48 >= 0 && chr_cnpj[i + 4] - 48 <= 9) {
                soma += (chr_cnpj[i + 4] - 48) * (10 - (i + 1));
            }
        }

        int dig = 11 - soma % 11;
        cnpj_calc = new StringBuilder(String.valueOf(cnpj_calc)).append(
                dig != 10 && dig != 11 ? Integer.toString(dig) : "0")
                .toString();
        soma = 0;
        for (int i = 0; i < 5; i++) {
            if (chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9) {
                soma += (chr_cnpj[i] - 48) * (7 - (i + 1));
            }
        }

        for (int i = 0; i < 8; i++) {
            if (chr_cnpj[i + 5] - 48 >= 0 && chr_cnpj[i + 5] - 48 <= 9) {
                soma += (chr_cnpj[i + 5] - 48) * (10 - (i + 1));
            }
        }

        dig = 11 - soma % 11;
        cnpj_calc = new StringBuilder(String.valueOf(cnpj_calc)).append(
                dig != 10 && dig != 11 ? Integer.toString(dig) : "0")
                .toString();

        return cnpj.equals(cnpj_calc);
    }
}